<template>
  <div class="container" style="height: 100%">
    <div class="flex_cm" style="height: 100%">
      <search
        :data="header_list"
        @changeIsShow="
          (e) => {
            header_list[e].isShow = !header_list[e].isShow
            header_list[e].value = ''
          }
        "
        @search="search_key"
        @reset="
          header_list.forEach((item) => {
            item.value = ''
          }),
            search_key()
        "
      ></search>
      <div class="p_0_10 bg_fff flex1">
        <div class="flex_js p_10_0">
          <div class="c_666 fw">角色列表</div>
          <div class="flex">
            <el-button
              type="primary"
              v-if="has_role_list[3].has_role"
              @click="show_box = true"
              >新增角色</el-button
            >

            <setTable
              :data="header_list"
              :height_size="height_size"
              @changeShowTable="
                (e) => {
                  header_list[e].showTable = !header_list[e].showTable
                }
              "
              @resetTableSet="
                () => {
                  header_list.forEach((item) => {
                    item.showTable = true
                  })
                }
              "
              @changeHeightSize="
                (e) => {
                  height_size = e
                }
              "
            ></setTable>
          </div>
        </div>
        <myTable
          :data="list"
          :maxHeight="max_height"
          :height_size="height_size"
          :loading="loading"
          :header_list="header_list"
          @edit_list="edit_list"
        ></myTable>
      </div>
    </div>
    <el-drawer
      v-model="show_box"
      direction="rtl"
      size="50%"
      destroy-on-close
      @close="resetForm(addroleform)"
      :close-on-click-modal="false"
    >
      <template #title>
        <h4 v-if="add_form_data.id == ''">新增角色</h4>
        <h4 v-else>修改角色</h4>
      </template>
      <template #default style="font-size: 14px">
        <el-form
          :model="add_form_data"
          :rules="rules"
          ref="addroleform"
          label-width="100px"
        >
          <el-form-item label="角色名称" prop="name">
            <el-input
              v-model="add_form_data.name"
              placeholder="请输入角色名称"
              show-word-limit
              maxlength="30"
            ></el-input>
          </el-form-item>
          <el-form-item label="角色代号" prop="code">
            <el-input
              v-model="add_form_data.code"
              placeholder="请输入角色代号"
              show-word-limit
              maxlength="30"
            ></el-input>
          </el-form-item>
          <el-form-item label="角色类型">
            <el-radio v-model="add_form_data.platformType" disabled :label="1"
              >平台角色</el-radio
            >
            <el-radio v-model="add_form_data.platformType" disabled :label="2"
              >企业角色</el-radio
            >
          </el-form-item>
          <el-form-item
            label="企业角色等级"
            v-if="add_form_data.platformType == 2"
          >
            <el-select
              v-model="add_form_data.enterLevelId"
              style="width: 250px"
              :disabled="add_form_data.id != ''"
            >
              <el-option
                v-for="(item, index) in enterprise_level_list"
                :key="index"
                :label="item.name"
                :value="item.id"
              ></el-option>
            </el-select>
          </el-form-item>
          <el-form-item
            label="角色产品类型"
            v-if="add_form_data.platformType == 2"
          >
            <el-select
              v-model="add_form_data.productId"
              style="width: 250px"
              :disabled="add_form_data.id != ''"
            >
              <el-option
                v-for="item in product_list"
                :key="item.id"
                :label="item.dictValue"
                :value="item.dictCode"
              ></el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="状态">
            <el-radio
              v-model="add_form_data.status"
              :disabled="!has_role_list[0].has_role"
              :label="1"
              >启用</el-radio
            >
            <el-radio
              v-model="add_form_data.status"
              :disabled="!has_role_list[0].has_role"
              :label="0"
              >停用</el-radio
            >
          </el-form-item>
          <el-form-item label="角色描述">
            <el-input
              type="textarea"
              rows="4"
              v-model="add_form_data.description"
              placeholder="请输入角色描述"
              show-word-limit
              maxlength="300"
            ></el-input>
          </el-form-item>
          <el-divider></el-divider>
          <div style="color: #606266; margin-top: 10px">
            权限分配（拥有菜单权限及拥有列表权限）
          </div>
          <el-tree
            class="tree"
            :data="add_form_data.platformType == 2 ? role_data_2 : role_data_1"
            show-checkbox
            node-key="id"
            ref="tree"
            :props="defaultProps"
          />
          <div class="tr m_top10">
            <el-button @click=";(show_box = false), resetForm(addroleform)"
              >取消</el-button
            >
            <el-button
              type="primary"
              @click="submit(addroleform)"
              :loading="btn_loading"
              >保存</el-button
            >
          </div>
        </el-form>
      </template>
    </el-drawer>
  </div>
</template>
<script lang="ts" setup>
import { check_role, handle_search_key } from '@/utils/utils' // 权限校验
import search from '@/view/components/search.vue' // 搜索组件
import setTable from '@/view/components/setTable.vue' // 列表顶部右侧操作图标
import myTable from '@/view/components/myTable.vue'
import { ref, nextTick, reactive, computed, onMounted, onUnmounted } from 'vue'
import { FormInstance, ElMessage, ElMessageBox } from 'element-plus'
import axios from '@/service/HttpRequest'
import serviceApi from '@/service/api'
import EventBus from '@/utils/EventBus'
import { useStore } from 'vuex'
const store = useStore()
const addroleform = ref<FormInstance>()
const customize = (rule: any, value: any, callback: any) => {
  // 角色代号表单校验
  if (!value) {
    return callback(new Error('请输入角色代号'))
  }
  setTimeout(() => {
    var reg = new RegExp('[\\u4E00-\\u9FFF]+', 'g')
    if (reg.test(value)) {
      callback(new Error('角色代号不能包含汉字'))
    } else {
      callback()
    }
  }, 1000)
}
const rules = reactive({
  name: [{ required: true, message: '请输入角色名称', trigger: 'blur' }],
  code: [{ required: true, validator: customize, trigger: 'blur' }],
})
// 该页面权限组
const has_role_list = ref([
  { path: 'role/status', has_role: false },
  { path: 'role/put', has_role: false },
  { path: 'role/delete', has_role: false },
  { path: 'role/post', has_role: false },
])
const max_height = ref()
const loading = ref(false)
const total = ref()
const show_box = ref(false)
const form_data = ref({
  // 列表请求数据
  current: 1,
  description: '',
  name: '',
  code: '',
  pageSize: 100,
  platformType: '',
  status: '',
})
const add_form_data = ref({
  // 表单请求数据
  id: '',
  name: '',
  code: '',
  status: 1,
  description: '',
  platformType: 1,
  enterLevelId: '2',
  roleRouteDealVOList: [],
  productId: '1',
})
const defaultProps = {
  // 权限树参数
  children: 'children',
  label: 'label',
  isLeaf: 'leaf',
}
const height_size = ref(1) // 列表行高
const header_list = ref<any>([
  // 列表表头控制  搜索参数
  {
    label: '名称',
    value: '',
    showTable: true,
    type: 'input',
    isShow: true,
    options: [],
    prop: 'name',
  },
  {
    label: '代号',
    value: '',
    showTable: true,
    type: 'input',
    isShow: true,
    options: [],
    prop: 'code',
  },
  {
    label: '角色类型',
    value: '',
    showTable: true,
    type: 'select',
    isShow: false,
    options: [
      { label: '平台', value: '1' },
      { label: '企业', value: '2' },
    ],
    prop: 'platformType',
  },
  {
    label: '状态',
    value: '',
    showTable: true,
    type: 'select',
    isShow: false,
    options: [
      { label: '已启用', value: '1' },
      { label: '已停用', value: '0' },
    ],
    prop: 'status',
  },
  {
    label: '角色描述',
    value: '',
    showTable: true,
    type: 'input',
    isShow: false,
    options: [],
    prop: 'description',
  },
])
const list = ref()
const role_data_1 = ref() // 平台权限组
const role_data_2 = ref() // 企业权限组
const tree = ref(null)
onMounted(() => {
  max_height.value = window.innerHeight - 280 // 带分页的 table 高度
  has_role_list.value.forEach((item) => {
    item.has_role = check_role(item.path)
  })
  EventBus.on('refresh', () => {
    // 刷新
    get_list()
    ElMessage.success('刷新成功！')
  })
  get_list()
  get_role_list()
  get_enterprise_level_list()
})
onUnmounted(() => {
  EventBus.off('refresh')
})
const product_list = computed(() => {
  return store.state.product_list
})
const enterprise_level_list = ref()
const get_enterprise_level_list = () => {
  axios
    .request({
      url: serviceApi.enterprise_level_list,
      method: 'post',
    })
    .then((res) => {
      res.data.splice(0, 1)
      enterprise_level_list.value = res.data
    })
    .catch((error) => {
      ElMessage.error(error)
    })
}
const btn_loading = ref(false)
const submit = async (formEl: FormInstance | undefined) => {
  var a = tree.value.getCheckedNodes(false, true) // 获取选中节点  包含半选中
  console.log(a)
  if (!a.length) {
    ElMessage.warning('至少分配一项权限！')
    return
  }
  for (let i in a) {
    // 拥有菜单权限  赋予列表全选
    if (
      (a[i].type == 2 || a[i].type == 3) &&
      a[i].children &&
      a[i].children.length &&
      a[i].children[0].type == 4
    ) {
      a.push(a[i].children[0])
    }
  }
  for (let i in a) {
    var b = { routeId: a[i].id }
    add_form_data.value.roleRouteDealVOList.push(b)
  }
  await formEl.validate((valid) => {
    console.log(valid, add_form_data.value)
    if (valid) {
      if (btn_loading.value) return
      btn_loading.value = true
      axios
        .request({
          url:
            add_form_data.value.id == ''
              ? serviceApi.role_crud
              : serviceApi.role_crud + '/' + add_form_data.value.id,
          method: add_form_data.value.id == '' ? 'post' : 'put',
          data: add_form_data.value,
        })
        .then((res) => {
          console.log(res)
          ElMessage.success('操作成功！')
          setTimeout(() => {
            get_list()
            show_box.value = false
            btn_loading.value = false
          }, 1000)
        })
        .catch((error) => {
          btn_loading.value = false
          ElMessage.error(error)
        })
    }
  })
}
const resetForm = (formEl: FormInstance | undefined) => {
  // 取消表单验证  还原参数
  if (!formEl) return
  formEl.resetFields()
  add_form_data.value = {
    id: '',
    name: '',
    code: '',
    status: 1,
    description: '',
    platformType: 1,
    enterLevelId: '2',
    roleRouteDealVOList: [],
    productId: '1',
  }
  tree.value.setCheckedKeys([], true)
}
const search_key = () => {
  // 搜索
  form_data.value = {
    current: 1,
    code: header_list.value[1].value,
    name: header_list.value[0].value,
    description: header_list.value[4].value,
    pageSize: 100,
    status: parseInt(header_list.value[3].value) as any,
    platformType: header_list.value[2].value,
  }
  handle_search_key(form_data.value)
  get_list()
}
const edit_list = (e) => {
  console.log(e)
  if (e.type == 1 || e.type == 2) {
    ElMessageBox.confirm(
      e.item.status ? '确定停用该记录？' : '确定启用该记录？',
      '',
      {
        closeOnClickModal: false,
        type: 'warning',
      }
    )
      .then(() => {
        axios
          .request({
            url:
              e.item.status == 1
                ? serviceApi.role_disable + '/' + e.item.id
                : serviceApi.role_enable + '/' + e.item.id,
            method: 'put',
          })
          .then(() => {
            ElMessage.success('操作成功！')
            setTimeout(() => {
              get_list()
            }, 1000)
          })
          .catch((error) => {
            ElMessage.error(error)
          })
      })
      .catch(() => {})
  } else if (e.type == 3) {
    update_role(e.item)
  } else {
    ElMessageBox.confirm('确定删除该记录？', '', {
      closeOnClickModal: false,
      type: 'warning',
    })
      .then(() => {
        axios
          .request({
            url: serviceApi.role_crud + '/' + e.item.id,
            method: 'delete',
          })
          .then(() => {
            ElMessage.success('删除成功！')
            setTimeout(() => {
              get_list()
            }, 1000)
          })
          .catch((error) => {
            ElMessage.error(error)
          })
      })
      .catch(() => {})
  }
}
const update_role = (e) => {
  axios
    .request({ url: serviceApi.role_crud + '/' + e.id, method: 'get' })
    .then((res) => {
      console.log(res)
      add_form_data.value = {
        platformType: res.data.platformType ? res.data.platformType : 1,
        enterLevelId: res.data.levelId ? res.data.levelId + '' : '2',
        id: res.data.id,
        name: res.data.name,
        code: res.data.code,
        status: res.data.status ? 1 : 0,
        description: res.data.description,
        productId: res.data.productId ? res.data.productId : '1',
        roleRouteDealVOList:
          res.data.roleRouteDTOList ?? '' == ''
            ? []
            : res.data.roleRouteDTOList,
      }
      show_box.value = true
      let default_checked = []
      if (
        res.data.roleRouteDTOList.length &&
        (res.data.roleRouteDTOList ?? '') !== ''
      ) {
        for (let i in res.data.roleRouteDTOList) {
          default_checked.push(res.data.roleRouteDTOList[i].routeId)
        }
      }
      console.log(default_checked)
      show_box.value = true
      nextTick(() => {
        default_checked.forEach((item) => {
          let node = tree.value.getNode(item)
          if (node.isLeaf) {
            tree.value.setChecked(node, true)
          }
        })
      })
    })
    .catch((error) => {
      ElMessage.error(error)
    })
}
const get_list = () => {
  loading.value = true
  axios
    .request({
      url: serviceApi.role_list,
      method: 'post',
      data: form_data.value,
    })
    .then((res) => {
      console.log(res)
      res.data.content.forEach((i) => {
        i.btn_list = [
          {
            label: '禁用',
            icon: 'table_status_enable',
            has_role: has_role_list.value[0].has_role,
            btn_show: i.status && i.platformType == 1,
          },
          {
            label: '启用',
            icon: 'table_status_disable',
            has_role: has_role_list.value[0].has_role,
            btn_show: !i.status && i.platformType == 1,
          },
          {
            label: '编辑',
            icon: 'table_edit',
            has_role: has_role_list.value[1].has_role,
            btn_show: true,
          },
          {
            label: '删除',
            icon: 'table_delete',
            has_role: has_role_list.value[2].has_role,
            btn_show: true && i.platformType == 1,
          },
        ]
      })
      list.value = res.data.content
      total.value = parseInt(res.data.totalElements)
      loading.value = false
    })
    .catch((error) => {
      loading.value = false
      ElMessage.error(error)
    })
}
const get_role_list = () => {
  axios
    .request({ url: serviceApi.router_list, method: 'post' })
    .then((res) => {
      console.log(res)
      var list_1 = []
      var list_2 = []
      for (let i in res.data) {
        if (res.data[i].platformType == 1) {
          list_1.push(res.data[i])
        } else {
          list_2.push(res.data[i])
        }
      }
      role_data_1.value = arrToTree(list_1.reverse())
      role_data_2.value = arrToTree(list_2.reverse())
      console.log(role_data_1, role_data_2)
    })
    .catch((error) => {
      ElMessage.error(error)
    })
}
const arrToTree = (list) => {
  var map = {}
  var result = []
  list.forEach((item) => {
    map[item.id] = item
  })
  list.forEach((item) => {
    item.label = item.name
    item.value = item.id
    item.disabled =
      item.name == '企业控制台' ||
      item.name == '运行环境设置' ||
      item.name == '企业信息' ||
      item.name == '系统日志'
        ? true
        : false
    let parent = map[item.parentId]
    if (parent) {
      if (!parent.children) {
        parent.children = []
      }
      item = Object.assign(item, { leaf: true })
      parent.children.push(item)
    } else {
      item = Object.assign(item, { leaf: true })
      result.push(item)
    }
  })
  return result
}
const treeToArray = (tree) => {
  var res = []
  for (const item of tree) {
    const { children, ...i } = item
    if (children && children.length) {
      res = res.concat(treeToArray(children))
    }
    res.push(i)
  }
  return res
}
</script>
<style lang="scss" scoped>
.tree {
  margin-top: 10px;
  max-height: 500px;
  overflow-y: scroll;
  border: 1px solid #acacac;
}
:deep(.el-switch__core) {
  width: 70px !important;
}
</style>
